package com.test.base.mq;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.support.converter.AbstractMessageConverter;
import org.springframework.amqp.support.converter.ClassMapper;
import org.springframework.messaging.converter.MessageConversionException;

import com.alibaba.fastjson.JSON;

import lombok.extern.slf4j.Slf4j;

/**
 * 自定义消息转换器 采用FastJson完成消息转换
 * 
 * @author: 许自辉
 * @date: 2018年7月2日 下午4:31:55
 */
@Slf4j
public class RabbitMqFastJsonConverter extends AbstractMessageConverter {

	/**
	 * 消息类型映射对象
	 */
	private static ClassMapper classMapper = new RabbitMqFastJsonClassMapper();
	/**
	 * 默认字符集
	 */
	private static String DEFAULT_CHART_SET = "UTF-8";

	/**
	 * 创建消息
	 *
	 * @param o
	 *            消息对象
	 * @param messageProperties
	 *            消息属性
	 * @return
	 */
	@Override
	protected Message createMessage(Object o,
			MessageProperties messageProperties) {
		byte[] bytes = null;
		try {
			String jsonString = JSON.toJSONString(o);
			bytes = jsonString.getBytes(DEFAULT_CHART_SET);
		} catch (IOException e) {
			throw new MessageConversionException(
					"Failed to convert Message content", e);
		}
		messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
		messageProperties.setContentEncoding(DEFAULT_CHART_SET);
		if (bytes != null) {
			messageProperties.setContentLength(bytes.length);
		}
		classMapper.fromClass(o.getClass(), messageProperties);
		return new Message(bytes, messageProperties);
	}

	/**
	 * 转换消息为对象
	 *
	 * @param message
	 *            消息对象
	 * @return
	 * @throws MessageConversionException
	 */
	@Override
	public Object fromMessage(Message message)
			throws MessageConversionException {
		Object content = null;
		MessageProperties properties = message.getMessageProperties();
		if (properties != null) {
			String contentType = properties.getContentType();
			if (contentType != null && contentType.contains("json")) {
				String encoding = properties.getContentEncoding();
				if (encoding == null) {
					encoding = DEFAULT_CHART_SET;
				}
				try {
					Class<?> targetClass = classMapper
							.toClass(message.getMessageProperties());

					content = convertBytesToObject(message.getBody(), encoding,
							targetClass);
				} catch (IOException e) {
					throw new MessageConversionException(
							"Failed to convert Message content", e);
				}
			} else {
				log.warn(
						"Could not convert incoming message with content-type ["
								+ contentType + "]");
			}
		}
		if (content == null) {
			content = message.getBody();
		}
		return content;
	}

	/**
	 * 将字节数组转换成实例对象
	 *
	 * @param body
	 *            Message对象主体字节数组
	 * @param encoding
	 *            字符集
	 * @param clazz
	 *            类型
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private Object convertBytesToObject(byte[] body, String encoding,
			Class<?> clazz) throws UnsupportedEncodingException {
		String contentAsString = new String(body, encoding);
		return JSON.parseObject(contentAsString, clazz);
	}

}
